/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Modified Queplix BSD License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/BSDLICENSE-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.jlect.swebing.ui.client.menu;

import com.jlect.swebing.renderers.client.Image;
import com.jlect.swebing.renderers.client.PopupListener;
import com.jlect.swebing.renderers.client.RendererEvent;
import com.jlect.swebing.renderers.client.RendererKeyEvent;
import com.jlect.swebing.ui.client.*;

/**
 * Menu component, that allows client to combine together instances of
 * {@link com.jlect.swebing.ui.client.menu.GMenuItem} class.
 *
 * @author Sergey Kozmin
 * @since Nov 26, 2007
 */
public class GMenu extends GMenuItem implements ActionListener {
    private GContainer items;
    private GPopupMenu popup;

    private SingleSelectionController selectionController;

    public GMenu(String text, Image image) {
        super(text, image);
        items = new GContainer(new FlowLayout());
        items.setOrientation(new ComponentOrientation(true, false));
        items.setPreferredSize(new Dimension(120, 300));
        selectionController = new SingleSelectionController();
    }

    public GMenu(String text) {
        this(text, null);
    }

    public void addMenuItem(GMenuItem item) {
        items.addComponent(item);
        item.addActionListener(this);
        selectionController.addComponent(item);
    }

    public void removeMenuItem(GMenuItem item) {
        items.removeComponent(item);
        if(item != null) {
            item.removeActionListener(this);
            selectionController.removeComponent(item);
        }
    }

    public GComponent removeMenuItem(int index) {
        GComponent component = items.removeComponent(index);
        if(component instanceof GMenuItem) {
            GMenuItem item = (GMenuItem) component;
            item.removeActionListener(this);
            selectionController.removeComponent(item);
        }
        return component;
    }

    public void addMenuItem(String text) {
        items.addComponent(new GMenuItem(text));
    }

    /**
     * When user clicks on the gmenu it shows itself
     * @param event renderer event
     */
    public void fireActionPerformed(RendererEvent event) {
        showPopup(getX() + getWidth(), getY());

//        do not generate action events until down component generate it. It doesn't generate it by itself
//        super.fireActionPerformed(event);
    }

    public void showPopup(int x, int y) {
        ensurePopupCreated();
        popup.setLocation(x, y);
        popup.setVisible(true);
    }

    public void hidePopup() {
        if(popup != null && popup.isVisible()) {
            popup.setVisible(false);
        }
    }

    public void addPopupListener(PopupListener listener) {
        ensurePopupCreated();//todo call only on open action, store listeners here
        popup.addPopupListener(listener);
    }

    public void removePopupListener(PopupListener listener) {
        if(popup != null) {
            popup.removePopupListener(listener);
        }
    }

    private void ensurePopupCreated() {
        if(popup == null) {
            popup = new GPopupMenu(new BorderLayout());
            popup.addComponent(items, BorderLayout.CENTER);
        }
    }

    /**
     * This method is called when inner menu items generate action event
     * @param event evemt
     */
    public void actionPerformed(ActionEvent event) {
        hidePopup();
        getActionListeners().actionPerformed(event);
    }

    protected void fireKeyEvent(RendererKeyEvent event) {
        //@todo handle "left" key and if this component selected, then show popup
        //todo handle "right" key in opposite way
        super.fireKeyEvent(event);
    }
}
